﻿#include "GUIFESubSysStructDialog.h"
#include "ui_GUIFESubSysStructDialog.h"
#include "FITK_Component/FITKAcousticsModel/FITKAbstractSEASubSys.h"
#include "FITK_Component/FITKAcousticsModel/FITKFESubSysStructure.h"
#include "FITK_Component/FITKAcousticsModel/FITKAcousticsDiscModel.h"
#include "FITK_Component/FITKAcousticsModel/FITKAcousticsFEModel.h"
#include "FITK_Component/FITKAcousticsModel/FITKAcousticsDiscNodeList.h"
#include "FITK_Interface/FITKInterfaceModel/FITKAbstractElement.h"
#include "FITK_Interface/FITKInterfacePhysics/FITKAbstractSection.h"
#include "FITK_Kernel/FITKCore/FITKVec3D.h"

#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsPhysics.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsSpectraManager.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsAbstractSpectra.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsAbsPhysicsProp.h"

#include "FITK_Kernel/FITKAppFramework/FITKAppFramework.h"
#include "FITK_Kernel/FITKAppFramework/FITKAppSettings.h" 
#include "FITK_Kernel/FITKAppFramework/FITKGlobalData.h"

#include <QStandardItemModel>

namespace GUI {
    GUIFESubSysStructDialog::GUIFESubSysStructDialog(Acoustics::FITKFESubSysStructure* obj, Core::FITKActionOperator* oper, QWidget* parent /*= nullptr*/) :
        GUIFESubSysBaseDialog(obj, oper, parent),
        _ui(new Ui::GUIFESubSysStructDialog)
    {
        _ui->setupUi(this);
        //初始化界面
        this->initWidgetImage();
        //初始化表格
        _tableView_Attributes = new QStandardItemModel();
        _ui->tableView_Attributes->setModel(_tableView_Attributes);
        _tableView_Elements = new QStandardItemModel();
        _ui->tableView_Elements->setModel(_tableView_Elements);
        _tableView_Nodes = new QStandardItemModel();
        _ui->tableView_Nodes->setModel(_tableView_Nodes);
        //移除faces页
        _ui->tabWidget->removeTab(1);
        //设置属性隐藏
        _ui->groupBox_Beam->setEnabled(false);
        _ui->groupBox_Shell->setEnabled(false);
        _ui->groupBox_Solid->setEnabled(false);
        //初始化
        this->init();
    }

    GUIFESubSysStructDialog::~GUIFESubSysStructDialog()
    {
        //释放数据
        if (_ui) {
            delete _ui;
            _ui = nullptr;
        }
        if (_tableView_Attributes) delete _tableView_Attributes;
        if (_tableView_Elements) delete _tableView_Elements;
        if (_tableView_Nodes) delete _tableView_Nodes;
    }

    void GUIFESubSysStructDialog::init()
    {
        Acoustics::FITKFESubSysStructure* data = dynamic_cast<Acoustics::FITKFESubSysStructure*>(_obj);
        if (!data || !_oper) return;
        //初始化界面参数
        this->initDampingLossComboBox();
        //初始化数据
        QString name = _obj->getDataObjectName();
        if (name.isEmpty())
        {
            name = "FE Structural-1";
            name = this->ckeckNameFromMgr(name);
        }
        int dampingID = data->getDampingLossSpectraID();
        if (dampingID < 0)
            _oper->argValue<int>("DampingLossID", dampingID);
        bool isEnableState = data->getEnableState();
        //设置界面数据
        _ui->lineEdit_Name->setText(name);
        int index = _ui->comboBox_DampingLoss->findData(dampingID);
        _ui->comboBox_DampingLoss->setCurrentIndex(index);
        _ui->checkBox_EnabledState->setCheckState((isEnableState ? Qt::CheckState::Checked : Qt::CheckState::Unchecked));
        this->initTableViewAttributes();
        this->initTableViewElements();
        this->initTableViewNodes();
        this->initPropData();
    }

    void GUIFESubSysStructDialog::on_pushButton_Cancel_clicked()
    {
        //点击取消按键动作
        this->reject();
    }

    void GUIFESubSysStructDialog::on_pushButton_OK_clicked()
    {
        if (!_oper)return;
        //获取操作器动作类型
        QString operType;
        _oper->argValue<QString>("OperModelType", operType);
        if (operType.isEmpty())
        {
            delete _obj;
            this->reject();
            return;
        }
        //创建动作
        if (operType == "Create")
        {
            if (!this->createObjData())
                return;
        }
        //修改动作
        else if (operType == "Edit")
        {
            if (!this->editObjData())
                return;
        }
        this->accept();
    }

    void GUIFESubSysStructDialog::on_radioButton_ShellPhyProp_toggled(bool checkState)
    {
        if (checkState == true)
        {
            _ui->comboBox_ShellPhyProp->setEnabled(true);
            this->on_comboBox_ShellPhyProp_currentIndexChanged(_ui->comboBox_ShellPhyProp->currentIndex());
            _ui->comboBox_ShellFEProp->setEnabled(false);
        }
    }

    void GUIFESubSysStructDialog::on_radioButton_ShellFEProp_toggled(bool checkState)
    {
        if (checkState == true)
        {
            _ui->comboBox_ShellFEProp->setEnabled(true);
            this->on_comboBox_ShellFEProp_currentIndexChanged(_ui->comboBox_ShellFEProp->currentIndex());
            _ui->comboBox_ShellPhyProp->setEnabled(false);
        }
    }

    void GUIFESubSysStructDialog::on_comboBox_ShellPhyProp_currentIndexChanged(int index)
    {
         _tableView_Attributes->setData(_tableView_Attributes->index(2, 2), _ui->comboBox_ShellPhyProp->currentText());
         int count = _tableView_Elements->rowCount();
         for (int i = 0; i < count; ++i)
         {
             _tableView_Elements->setData(_tableView_Elements->index(i, 1), _ui->comboBox_ShellPhyProp->currentText());
         }
    }

    void GUIFESubSysStructDialog::on_comboBox_ShellFEProp_currentIndexChanged(int index)
    {
        _tableView_Attributes->setData(_tableView_Attributes->index(2, 2), _ui->comboBox_ShellPhyProp->currentText());
        int count = _tableView_Elements->rowCount();
        for (int i = 0; i < count; ++i)
        {
            _tableView_Elements->setData(_tableView_Elements->index(i, 1), _ui->comboBox_ShellPhyProp->currentText());
        }
    }

    void GUIFESubSysStructDialog::updateTableViewElements(QString propName)
    {
        if (!_tableView_Elements) return;
        //更新属性
        int rowCount = _tableView_Elements->rowCount();
        for (int i = 0; i < rowCount; ++i)
        {
            _tableView_Elements->setData(_tableView_Elements->index(i, 1), propName);
        }
    }

    void GUIFESubSysStructDialog::initWidgetImage()
    {
        //初始化图像
        _ui->label_Image->setPixmap(QPixmap(":/ToolBar/toolBar/FE_structural_subsystem.png"));
    }

    void GUIFESubSysStructDialog::initTableViewAttributes()
    {
        if (!_obj) return;
        //获取属性
        QList<int> nodeIDs = _obj->getNodesID();
        QList<int> elemIDs = _obj->getElementsID();
        QList<QString> propNames = _obj->getAllElementPropName();
        QString nodeStr = this->getIDListConsolidatedStr(nodeIDs);
        QString elemStr = this->getIDListConsolidatedStr(elemIDs);
        //写出属性表格
        _tableView_Attributes->clear();
        QStringList tableView_h_headers;
        tableView_h_headers << tr("Attribute") << tr("Count") << tr("IDs");
        _tableView_Attributes->setHorizontalHeaderLabels(tableView_h_headers);
        _tableView_Attributes->appendRow(QList<QStandardItem*>() << new QStandardItem("Elements") << new QStandardItem(QString::number(elemIDs.size())) << new QStandardItem(elemStr));
        _tableView_Attributes->appendRow(QList<QStandardItem*>() << new QStandardItem("Nodes") << new QStandardItem(QString::number(nodeIDs.size())) << new QStandardItem(nodeStr));
        _tableView_Attributes->appendRow(QList<QStandardItem*>() << new QStandardItem("Property Cards") << new QStandardItem(QString::number(propNames.size())) << new QStandardItem(propNames.join(',')));
        // 表格宽度自动根据UI进行计算，不可手动调整宽度
        _ui->tableView_Attributes->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
        _ui->tableView_Attributes->setEditTriggers(QAbstractItemView::NoEditTriggers);
    }

    void GUIFESubSysStructDialog::initTableViewElements()
    {
        if (!_obj) return;
        //获取离散数据
        Acoustics::FITKAcousticsDiscModel* discMgr = FITKAPP->getGlobalData()->getMeshData<Acoustics::FITKAcousticsDiscModel>();
        if (!discMgr) return;
        //获取FE子系统管理器
        Acoustics::FITKAcousticsFEModel* feModel = discMgr->getFEModel();
        if (!feModel) return;
        //获取单元管理器
        Acoustics::FITKAcousticsFESubSysElementList* elementList = feModel->getFESubSysElementList();
        if (!elementList) return;
        QList<int> elemIDs = _obj->getElementsID();
        //写出单元表格
        _tableView_Elements->clear();
        QStringList tVElement_h_headers;
        tVElement_h_headers << tr("Element ID") << tr("Property Name") << tr("Type") << tr("Node IDs");
        _tableView_Elements->setHorizontalHeaderLabels(tVElement_h_headers);
        for (int i = 0; i < elemIDs.size(); ++i)
        {
            int eID = elemIDs.at(i);
            //获取单元数据
            Interface::FITKAbstractElement* element = elementList->getElementByID(eID);
            if (!element) continue;
            QString propName = elementList->getElementPropName(eID);
            int dim = element->getElementDim();
            QList<int> nodes = element->getAllNodes();
            QStringList nodeIDStr;
            for (int nID : nodes)
                nodeIDStr.append(QString::number(nID));
            //设置表格内容
            _tableView_Elements->setItem(i, 0, new QStandardItem(QString::number(eID)));
            _tableView_Elements->setItem(i, 1, new QStandardItem(propName));
            if (dim == 2)
                _tableView_Elements->setItem(i, 2, new QStandardItem("Shell"));
            else if (dim == 1)
                _tableView_Elements->setItem(i, 2, new QStandardItem("Beam"));
            _tableView_Elements->setItem(i, 3, new QStandardItem(nodeIDStr.join("; ")));
        }
        // 表格宽度自动根据UI进行计算，不可手动调整宽度
        _ui->tableView_Elements->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
        _ui->tableView_Elements->setEditTriggers(QAbstractItemView::NoEditTriggers);
    }

    void GUIFESubSysStructDialog::initTableViewNodes()
    {
        if (!_obj) return;
        //获取离散数据
        Acoustics::FITKAcousticsDiscModel* discMgr = FITKAPP->getGlobalData()->getMeshData<Acoustics::FITKAcousticsDiscModel>();
        if (!discMgr) return;
        //获取节点管理器
        Acoustics::FITKAcousticsDiscNodeList* nodeList = discMgr->getNodes();
        if (!nodeList) return;
        QList<int> nodeIDs = _obj->getNodesID();
        //写出节点表格
        _tableView_Nodes->clear();
        QStringList tVNode_h_headers;
        tVNode_h_headers << tr("Node ID") << tr("X") << tr("Y") << tr("Z");
        _tableView_Nodes->setHorizontalHeaderLabels(tVNode_h_headers);
        for (int i = 0; i < nodeIDs.size(); ++i)
        {
            int nID = nodeIDs.at(i);
            //获取节点数据
            Core::FITKNode* node = nodeList->getNodeByID(nID);
            if (!node) continue;
            double coor[3]{ 0,0,0 };
            node->getCoor(coor);
            //设置表格内容
            _tableView_Nodes->setItem(i, 0, new QStandardItem(QString::number(nID)));
            _tableView_Nodes->setItem(i, 1, new QStandardItem(QString::number(coor[0])));
            _tableView_Nodes->setItem(i, 2, new QStandardItem(QString::number(coor[1])));
            _tableView_Nodes->setItem(i, 3, new QStandardItem(QString::number(coor[2])));
        }
        // 表格宽度自动根据UI进行计算，不可手动调整宽度
        _ui->tableView_Nodes->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
        _ui->tableView_Nodes->setEditTriggers(QAbstractItemView::NoEditTriggers);
    }

    void GUIFESubSysStructDialog::initDampingLossComboBox()
    {
        //清空数据下拉链表
        _ui->comboBox_DampingLoss->clear();
        //初始化损耗因子下拉列表
        Acoustics::FITKAcousticsPhysics* phyMgr = FITKAPP->getGlobalData()->getPhysicsData<Acoustics::FITKAcousticsPhysics>();
        if (!phyMgr)return;
        //获取频谱管理器
        Acoustics::FITKAcousticsSpectraManager* spectraMgr = phyMgr->getFITKAcousticsSpectraManager();
        if (!spectraMgr)return;
        QList<Acoustics::FITKAcousticsAbstractSpectra*> spectraList = spectraMgr->getSpectraByType(Acoustics::FITKAcousticsAbstractSpectra::AcousticsSpectraType::Damping);
        for (QList<Acoustics::FITKAcousticsAbstractSpectra*>::iterator iter = spectraList.begin(); iter != spectraList.end(); ++iter)
        {
            if (*iter == nullptr)continue;
            _ui->comboBox_DampingLoss->addItem((*iter)->getDataObjectName(), (*iter)->getDataObjectID());
        }
    }

    void GUIFESubSysStructDialog::initPropData()
    {
        if (!_obj) return;
        bool isFEProp = false;
        int dim = _obj->getElementDim();
        QList<int> propIDList = _obj->getAllElementPropID(&isFEProp);
        if (propIDList.isEmpty()) return;
        //清空数据下拉链表
        _ui->comboBox_BeamFEProp->clear();
        _ui->comboBox_BeamPhyProp->clear();
        _ui->comboBox_ShellFEProp->clear();
        _ui->comboBox_ShellPhyProp->clear();
        _ui->comboBox_SolidFEProp->clear();
        _ui->comboBox_SolidMaterialProp->clear();
        //获取离散数据
        Acoustics::FITKAcousticsDiscModel* discMgr = FITKAPP->getGlobalData()->getMeshData<Acoustics::FITKAcousticsDiscModel>();
        if (!discMgr) return;
        Acoustics::FITKAcousticsFEModel* feModel = discMgr->getFEModel();
        if (!feModel) return;
        Interface::FITKAbstractSectionManager* sectionMgr = feModel->getSectionManager();
        if (!sectionMgr) return;
        //初始化物理属性下拉列表
        Acoustics::FITKAcousticsPhysics* phyMgr = FITKAPP->getGlobalData()->getPhysicsData<Acoustics::FITKAcousticsPhysics>();
        if (!phyMgr)return;
        //获取物理属性管理器
        Acoustics::FITKAcousticsPhysicsPropManager* phyPropMgr = phyMgr->getPhysicsPropManager();
        if (!phyPropMgr)return;
        if (dim == 1)
        {
            _ui->groupBox_Beam->setEnabled(true);
            _ui->radioButton_BeamFEProp->setEnabled(false);
            QList<Acoustics::FITKAcousticsAbsPhysicsProp*> propDataList = phyPropMgr->getPhysicsProps(Acoustics::FITKAcousticsAbsPhysicsProp::AcousticsPhyscisPropType::APPBeam);
            for (QList<Acoustics::FITKAcousticsAbsPhysicsProp*>::iterator iter = propDataList.begin(); iter != propDataList.end(); ++iter)
            {
                if (*iter == nullptr)continue;
                _ui->comboBox_BeamPhyProp->addItem((*iter)->getDataObjectName(), (*iter)->getDataObjectID());
            }
            //FE属性设置
            if (isFEProp)
            {
                int index = _ui->comboBox_BeamPhyProp->findData(propIDList.at(0));
                _ui->comboBox_BeamPhyProp->setCurrentIndex(index);
                _ui->radioButton_BeamFEProp->setChecked(true);
            }
            else
            {
                int index = _ui->comboBox_BeamPhyProp->findData(propIDList.at(0));
                if (propIDList.size() > 1) index = -1;
                _ui->comboBox_BeamPhyProp->setCurrentIndex(index);
                _ui->radioButton_BeamPhyProp->setChecked(true);
            }
        }
        else if (dim == 2)
        {
            _ui->groupBox_Shell->setEnabled(true);
            QList<Acoustics::FITKAcousticsAbsPhysicsProp*> propDataList = phyPropMgr->getPhysicsProps(Acoustics::FITKAcousticsAbsPhysicsProp::AcousticsPhyscisPropType::APPUniformPlat);
            for (QList<Acoustics::FITKAcousticsAbsPhysicsProp*>::iterator iter = propDataList.begin(); iter != propDataList.end(); ++iter)
            {
                if (*iter == nullptr)continue;
                _ui->comboBox_ShellPhyProp->addItem((*iter)->getDataObjectName(), (*iter)->getDataObjectID());
            }
            for (int i = 0; i < sectionMgr->getDataCount(); ++i)
            {
                Interface::FITKAbstractSection* section = sectionMgr->getDataByIndex(i);
                if (!section) continue;
                _ui->comboBox_ShellFEProp->addItem(section->getDataObjectName(), section->getDataObjectID());
            }
            //FE属性设置
            if (isFEProp)
            {
                int index = _ui->comboBox_ShellPhyProp->findData(propIDList.at(0));
                _ui->comboBox_ShellPhyProp->setCurrentIndex(index);
                _ui->radioButton_ShellFEProp->setChecked(true);
            }
            else
            {
                int index = _ui->comboBox_ShellPhyProp->findData(propIDList.at(0));
                if (propIDList.size() > 1) index = -1;
                _ui->comboBox_ShellPhyProp->setCurrentIndex(index);
                _ui->radioButton_ShellPhyProp->setChecked(true);
            }
        }
        else if (dim == 3)
        {
            _ui->groupBox_Solid->setEnabled(true);
        }
    }

    void GUIFESubSysStructDialog::getDataFormWidget()
    {
        Acoustics::FITKFESubSysStructure* data = dynamic_cast<Acoustics::FITKFESubSysStructure*>(_obj);
        if (!data) return;
        int dim = _obj->getElementDim();
        //从界面获取数据
        int dampingID = _ui->comboBox_DampingLoss->currentData().toInt();
        bool isEnableState = _ui->checkBox_EnabledState->checkState() == Qt::CheckState::Checked;
        int propID = -1;
        if (dim == 1)
        {
            if (_ui->radioButton_BeamFEProp->isChecked() && _ui->comboBox_BeamFEProp->currentIndex() != -1)
                propID = _ui->comboBox_BeamFEProp->currentData().toInt();
            else if (_ui->radioButton_BeamPhyProp->isChecked() && _ui->comboBox_BeamPhyProp->currentIndex() != -1)
                propID = _ui->comboBox_BeamPhyProp->currentData().toInt();
        }
        else if (dim == 2)
        {
            if (_ui->radioButton_ShellFEProp->isChecked() && _ui->comboBox_ShellFEProp->currentIndex() != -1)
                propID = _ui->comboBox_ShellFEProp->currentData().toInt();
            else if (_ui->radioButton_ShellPhyProp->isChecked() && _ui->comboBox_ShellPhyProp->currentIndex() != -1)
                propID = _ui->comboBox_ShellPhyProp->currentData().toInt();
        }
        else if (dim == 3)
        {
        }
        //设置数据
        data->setDampingLossSpectraID(dampingID);
        data->setEnableState(isEnableState);

        if (propID != -1)
            _obj->setAllElementPropID(propID);
    }

    QString GUIFESubSysStructDialog::getNameFormWidget()
    {
        return _ui->lineEdit_Name->text();
    }
}
